#include <iostream>
#include <cassert>
#include "thread.h"

void threadEntry(void *thread) {
	((Thread *)thread)->execute();
}

Thread::Thread(JobQueue& jobQueue) 
	:	jobQueue_ (jobQueue)
{
	start();
}

Thread::~Thread() {
	abort();
	pthread_join(thread_, NULL);
}

void Thread::start() {
	pthread_attr_t attr;
	pthread_attr_init (&attr);
	pthread_create(&thread_, &attr, (void * (*)(void *)) threadEntry, (void *)this);
	pthread_attr_destroy(&attr);
}

void Thread::abort() {
	pthread_cancel(thread_);
}

void Thread::execute() {
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	Job* job;
	while((job = jobQueue_.pop()) != NULL) {
		job->execute();
		delete job;
		jobQueue_.jobCompleted();
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
		pthread_testcancel();
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	}
}

